﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Text;

namespace Interface.Cache
{
    /// <summary>
    /// 公共缓存类
    /// </summary>
    public static class CommonCache
    {
        private static ObjectCache cache = MemoryCache.Default;

        /// <summary>
        /// 查询缓存是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>是否存在</returns>
        public static bool ExistsCache(string key)
        {
            return cache.Contains(key);
        }

        /// <summary>
        /// 根据缓存键移除缓存对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">缓存键</param>
        public static void RemoveCache(string key)
        {
            if (!cache.Contains(key)) return;

            cache.Remove(key);
        }

        /// <summary>
        /// 设置缓存对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="obj">缓存对象</param>
        /// <param name="expires">过期时间（单位：分钟）</param>
        public static void SetCache<T>(string key, T obj, double expires = 20) where T : class
        {
            CacheItemPolicy policy = new CacheItemPolicy()
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(expires)
            };

            cache.Set(key, obj, policy);
        }

        /// <summary>
        /// 根据缓存键获取缓存对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <returns>缓存对象</returns>
        public static T GetCache<T>(string key) where T : class
        {
            if (!cache.Contains(key)) return null;

            return cache.GetCacheItem(key).Value as T;
        }

        /// <summary>
        /// 获取缓存对象,如果不存在，则重新设置
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="func">缓存委托</param>
        /// <param name="expires">过期时间（单位：分钟）</param>
        /// <returns>缓存对象</returns>
        public static T GetCache<T>(string key, Func<T> func, double expires = 20) where T : class
        {
            if (!cache.Contains(key))
            {
                CacheItemPolicy policy = new CacheItemPolicy()
                {
                    AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(expires)
                };

                T obj = null;

                if (func != null)
                {
                    obj = func();

                    if (obj != null)
                    {
                        cache.Set(key, obj, policy);
                    }
                }

                return obj;
            }
            else { return cache.GetCacheItem(key).Value as T; };
        }
    }
}